淺拷貝與深拷貝


Posted by wayne201299 on 2023-09-21

情境:傳遞Object給dialog,在dialog中透過雙向綁定傳入的Object,在dialog中變更Object,因為在JavaScript中,Object的傳遞是call by reference,所以外部的Object也會一起被連動,有沒有辦法可以不讓Object被連動呢?

父層component.ts

Dialog component.ts

this.componentItem = this.config.data.componentItem;

Dialog .html

<ec-language-tab-panel [hasJP]="true" [(ngModel)]="componentItem.title['s']"></ec-language-tab-panel>

分析

在分析之前要先有JavaScript的基本認識,JavaScript中傳遞值的方式有兩種

  • Pass by value,傳遞的值型態為Primitive type,只傳value,參數間不會互相影響
  • Pass by reference,傳遞的值型態為Object,這個狀態下傳遞參數會被指向記憶體位址,參數會互相連動

解決方案

  • 將傳入的參數全部攤平,變成pass by value,但這個做法不是很簡潔,所以沒採用
  • 建立一個新物件並傳入原本物件的值,而不是址,避免連動
    • 淺拷貝(shallow copy)
      將原始物件的屬性複製到新物件中,但其內部的屬性仍然是原始物件的引用,意思是Object中的屬性必須要是Primitive Type,如果有屬性還是Object的話還是會跟原始的Object連動,所以才叫淺拷貝
      const copiedObject = Object.assign({}, originalObject);
      
    • 深拷貝(deep copy)
      將物件透過JSON.stringify轉成JSON字串,再將JSON字串轉成物件,也可以使用lodash 的 cloneDeep來達到,但需要額外引入library
      const copiedObject = JSON.parse(JSON.stringify(this.config.data.componentItem));
      

:::success
深拷貝works
:::

:::danger
淺拷貝因為這次操作的Object剛好是兩層的Object結構,所以沒作用
:::

效能

深拷貝效能較不好的原因

  • 深拷貝會創建一個新的物件
  • JSON.parse(JSON.stringify())執行的效能不是很理想

關於效能上的比對可以參考Stackoverflow上的這篇,裡面有對比


參考資料


#javascript







Related Posts

#Tailwind #Webpack resolve-url-loader cannot operate: CSS error

#Tailwind #Webpack resolve-url-loader cannot operate: CSS error

MTR04 W2 D17 陣列練習題

MTR04 W2 D17 陣列練習題

[15] 值 - NaN、Infinity

[15] 值 - NaN、Infinity


Comments